package tech.heptagram.staff.cas.config.cas.auth;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.security.cas.authentication.CasAssertionAuthenticationToken;
import org.springframework.security.core.userdetails.AuthenticationUserDetailsService;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.annotation.Resource;

import lombok.extern.slf4j.Slf4j;
import tech.heptagram.core.common.util.JsonUtil;
import tech.heptagram.staff.cas.config.cas.domain.AuthorityInfo;
import tech.heptagram.staff.cas.config.cas.domain.UserInfo;
import tech.heptagram.staff.cas.domain.po.Menu;
import tech.heptagram.staff.cas.domain.po.Role;
import tech.heptagram.staff.cas.service.staff.CasMenuService;
import tech.heptagram.staff.cas.service.staff.CasRoleService;
import tech.heptagram.staff.model.Staff;

/**
 * 认证校验,获取用户详情
 */
@Component
@Slf4j
public class CASUserDetailsService implements AuthenticationUserDetailsService<CasAssertionAuthenticationToken> {

    @Resource
    private CasRoleService casRoleService;

    @Resource
    private CasMenuService casMenuService;

    /**
     * spring security 默认角色的字符串表示前缀
     */
    private static String DEFAULT_ROLE_PREFIX = "ROLE_";


    @Override
    public UserDetails loadUserDetails(CasAssertionAuthenticationToken token) throws UsernameNotFoundException {
        UserInfo userInfo = null;
        //用户信息获取
        String staffJsonStr = (String) token.getAssertion().getPrincipal().getAttributes().get("userDetails");
        Staff staffResp = JsonUtil.fromJson(staffJsonStr, Staff.class);
        userInfo = new UserInfo();
        BeanUtils.copyProperties(staffResp, userInfo);
        String userName = StringUtils.isEmpty(userInfo.getNickName()) ? userInfo.getTrueName() : userInfo.getTrueName() + "(" + userInfo.getNickName() + ")";
        userInfo.setUsername(userName);

        //用户权限获取
        Set<AuthorityInfo> authorities = new HashSet<AuthorityInfo>();
        List<Role> roles = casRoleService.findRolesByStaffCode(userInfo.getCode());
        for (Role role : roles) {
            AuthorityInfo authorityInfo = new AuthorityInfo();
            authorityInfo.setType(AuthorityInfo.ROLE);
            authorityInfo.setAuthority(DEFAULT_ROLE_PREFIX + role.getId().toString());
            authorityInfo.setName(role.getName());
            authorityInfo.setText(role.getText());
            authorities.add(authorityInfo);
        }

        List<Menu> operates = casMenuService.findOperateByStaffCode(userInfo.getCode());
        for (Menu operate : operates) {
            AuthorityInfo authorityInfo = new AuthorityInfo();
            authorityInfo.setType(AuthorityInfo.OPERATE);
            authorityInfo.setAuthority(operate.getId().toString());
            authorityInfo.setName(operate.getName());
            authorityInfo.setText(operate.getPath());
            authorityInfo.setMenuId(operate.getParentId());
            authorities.add(authorityInfo);
        }

        userInfo.setAuthorities(authorities);

        return userInfo;
    }

}
